package vip.youngboy.freejump.db.impl.mysql;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import vip.youngboy.freejump.db.TableOperator;
import vip.youngboy.freejump.db.constrants.ColumnType;
import vip.youngboy.freejump.db.constrants.DBType;
import vip.youngboy.freejump.db.model.DBColumn;
import vip.youngboy.freejump.db.model.DBTable;

import java.util.Iterator;

public class MySqlTableOperator extends TableOperator {

    private static Logger logger = LoggerFactory.getLogger(MySqlTableOperator.class);

    public MySqlTableOperator(DBTable<? extends DBColumn> DBTable, JdbcTemplate jdbcTemplate) {
        super(DBTable, jdbcTemplate);
    }

    @Override
    public DBType supportDBType() {
        return DBType.MYSQL;
    }

    public void createTable() {
        if (this.isTableCreated()) {
            this.logger.debug("表[" + this.DBTable.getName() + "(" + this.DBTable.getComment() + ")]已存在数据库中，无需再次生成");
        } else {
            StringBuilder sql = new StringBuilder();
            sql.append("CREATE TABLE " + this.DBTable.getName() + " (\n");
            Iterator var2 = this.DBTable.getColumns().iterator();

            while (var2.hasNext()) {
                DBColumn DBColumn = (DBColumn) var2.next();
                sql.append(this.columnToSql(DBColumn) + ",\n");
            }

            sql.append("PRIMARY KEY (" + this.DBTable.getPkColumn().getName() + ")\n)");
            sql.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin ");
            if (StringUtils.isNotEmpty(this.DBTable.getComment())) {
                sql.append(" COMMENT='" + this.DBTable.getComment() + "'");
            }

            sql.append(";");
            this.jdbcTemplate.execute(sql.toString());
        }
    }

    public boolean isTableCreated() {
        String sql = "select count(1) from information_schema.TABLES t where table_name =?";
        return (Integer) this.jdbcTemplate.queryForObject(sql, Integer.class, new Object[]{this.DBTable.getName()}) > 0;
    }

    public void addColumn(DBColumn DBColumn) {
        StringBuilder sql = new StringBuilder();
        sql.append("ALTER TABLE " + this.DBTable.getName() + "");
        sql.append(" ADD COLUMN " + this.columnToSql(DBColumn) + ";");
        this.jdbcTemplate.execute(sql.toString());
    }

    public void updateColumn(DBColumn DBColumn) {
        StringBuilder sql = new StringBuilder();
        sql.append("ALTER TABLE " + this.DBTable.getName() + "");
        sql.append(" MODIFY COLUMN " + this.columnToSql(DBColumn) + ";");
        this.jdbcTemplate.execute(sql.toString());
    }

    public void dropColumn(String columnName) {
        StringBuilder sql = new StringBuilder();
        sql.append("ALTER TABLE " + this.DBTable.getName() + "");
        sql.append(" DROP COLUMN " + columnName + ";");
        this.jdbcTemplate.execute(sql.toString());
    }

    private String columnToSql(DBColumn DBColumn) {
        StringBuilder sb = new StringBuilder();
        sb.append("" + DBColumn.getName() + "");
        if (ColumnType.CLOB.equalsWithKey(DBColumn.getType())) {
            sb.append(" text");
        } else if (ColumnType.DATE.equalsWithKey(DBColumn.getType())) {
            sb.append(" datetime");
        } else if (ColumnType.NUMBER.equalsWithKey(DBColumn.getType())) {
            sb.append(" decimal(" + DBColumn.getLength() + "," + DBColumn.getDecimal() + ")");
        } else if (ColumnType.VARCHAR.equalsWithKey(DBColumn.getType())) {
            sb.append(" varchar(" + DBColumn.getLength() + ")");
        }

        if (!DBColumn.isRequired() && !DBColumn.isPrimary()) {
            sb.append(" NULL");
        } else {
            sb.append(" NOT NULL");
        }

        if (StringUtils.isNotEmpty(DBColumn.getDefaultValue())) {
            sb.append(" DEFAULT " + DBColumn.getDefaultValue() + "");
        }

        sb.append(" COMMENT '" + DBColumn.getComment() + "'");
        return sb.toString();
    }

}
